#
# Copyright (C) 2011: Gabriel Tremblay (initnull@gmail.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
from threading import Thread
import threading
from restful_lib import Connection
import json

__author__ = 'Gabriel Tremblay <initnull@gmail.com>'

# Async Tou.TV client,
# Warning : no locking, so instantiate a new one each time
class TouTvUtils(Thread):
    # Constants
    # user agents
    USER_AGENTS = {"iPhone" : "Tou.tv 1.1 rv:14 (iPhone; iPhone OS 4.2.1; fr_CA)",
                   "iPad" : "Tou.tv 1.1 rv:14 (iPad; iPhone OS 4.3; fr_CA)"}

    # Service urls
    SERVICE_URL = "http://api.tou.tv"
    LISTING_URL = "/v1/toutvapiservice.svc/json/GetPageRepertoire"
    SHOW_URL = "/v1/toutvapiservice.svc/json/GetPageEmission?emissionId="

    SERVICE_VALIDATE_URL = "http://api.radio-canada.ca"
    VALIDATION_URL = "/validationMedia/v1/Validation.html?appCode=thePlatform&deviceType=ipad&connectionType=wifi&output=json&idMedia="
    # deviceType=iphone4, ipad

    # Global dictionary
    directory = None

    # Caller callback args
    callback_args = None

    # Internal variables
    __base_url__ = None
    __target_url__ = None
    __callback__ = None
    __use_iphone__ = False
    __lock__ = threading.Lock()

    # Fetch the whole show Directory
    def fetchDirectory(self, callback, use_iphone=False, *callback_args):
        self.__base_url__ = self.SERVICE_URL
        self.__target_url__ = self.LISTING_URL
        self.__callback__ = callback
        self.__use_iphone__ = use_iphone
        self.callback_args = callback_args
        self.start()

    # Get all the episode with their details of a given show
    def fetchEpisodeDetails(self, show_id, callback, use_iphone=False, *callback_args):
        self.__base_url__ = self.SERVICE_URL
        self.__target_url__ = self.SHOW_URL + str(show_id)
        self.__callback__ = callback
        self.__use_iphone__ = use_iphone
        self.callback_args = callback_args
        self.start()

    # Validate and return the stream url for a given episode
    def getStreamUrl(self, episode_id, callback, use_iphone=False, *callback_args):
        self.__base_url__ = self.SERVICE_VALIDATE_URL
        self.__target_url__ = self.VALIDATION_URL + str(episode_id)
        self.__callback__ = callback
        self.__use_iphone__ = use_iphone
        self.callback_args = callback_args
        self.start()


    # Execute async call, parse the json and call the caller back
    def run(self):
        if self.__use_iphone__ is True:
            agentHeaders = {'User-Agent' : self.USER_AGENTS.get("iPhone")}
        else:
            agentHeaders = {'User-Agent' : self.USER_AGENTS.get("iPad")}

        connection = Connection(self.__base_url__)
        reply = connection.request_get(self.__target_url__, headers=agentHeaders)
        headers = reply.get('headers')
        body = reply.get("body")

        if body is None or len(body) <= 0:
            self.directory = None
        else:
            # Detect ill-formatted json
            if body.find('url') > -1:
                body = body[1:]
                decodedJson = json.loads(body)
                decodedDirectory = decodedJson
            else:
                decodedJson = json.loads(body)
                decodedDirectory = decodedJson.get("d")

            # if decodedJson is None, then request timed out.
            if decodedDirectory is not None:
                # "d" is their identifier for Directory content
                self.directory = dict(decodedDirectory)
            else:
                self.directory = None

        # Callback
        self.__callback__(self)

